// file:arch/x86/include/arch/pit.h
// autor:jiangxinpeng
// time:2021.1.19
// copyright:(C) 2020-2050 by jiangxinpeng,All right are reserved.

#ifndef ARCH_PIT_H
#define ARCH_PIT_H

// PIT(programe interrupt timer) 8253/8254
// 8253 Counter0 Real Clock(normally mode 3)
#define PIT_COUNTER0 0x40
// 8253 Counter1 RAM Refresh Counter(normally mode 2)
#define PIT_COUNTER1 0x41
// 8253 Counter2 Cassette and Speaker Function
#define PIT_COUNTER2 0x42
// 8253 Mode Control Register
/*
|7|6|5|4|3|2|1|0|   Mode Control Register
 | | | | | | |  --------bits0 BCD/Binary Mode       0 = 16-bits binary   1 = four-dight BCD
 | | | | | | |
 | | | | --------------bits3-1   Operator Mode     0 = Mode 0 (interrupt on terminal count)   1 = Mode 1 (hardware re-triggerable only-shot)
 | | | |
 | |  ------------------bits5-4   Access Mode       0 = Latch count value           1 = Access mode: high byte only
 | |                                                2 = Access mode: low bytes only 4 = Access mode: low/high byte
 ----------------------bits7-6   Select Channel     0 = channel 0   1 = channel 1  2 = channel 3   3 = Read-back command (8254 only)
*/
#define PIT_CTRL 0x43

// config timer freqency
#define TIMER_FREQENCY 1193100
#define COUNTER0_VALUE (TIMER_FREQENCY /HZ)

enum PitModeCtr
{
    // channel select
    PIT_MODE_COUNTER0 = (0 << 6),
    PIT_MODE_COUNTER1 = (1 << 6),
    PIT_MODE_COUNTER2 = (1 << 7),
    PIT_MODE_READ_BACK = (1 << 6) | (1 << 7),
    // access mode
    PIT_MODE_LATCHVAL = (0 << 4),
    PIT_MODE_MSB = (1 << 4),
    PIT_MODE_LSB = (1 << 5),
    PIT_MODE_MSB_LSB = (1 << 5) | (1 << 4),
    // operator mode
    PIT_MODE_0 = (0 << 1),
    PIT_MODE_1 = (1 << 1),
    PIT_MODE_2 = (1 << 2),
    PIT_MODE_3 = (1 << 2) | (1 << 1),
    PIT_MODE_4 = (1 << 3),
    PIT_MODE_5 = (1 << 3) | (1 << 1),
    // count mode
    PIT_MODE_BINARY = (0 << 0),
    PIT_MODE_BCD = (1 << 0)
};

#endif